package com.burningtower.service.impl;

import com.burningtower.entity.Cart;
import com.burningtower.entity.Product;
import com.burningtower.enums.LimitQuantity;
import com.burningtower.repo.CartRepository;
import com.burningtower.service.CartService;
import com.burningtower.service.ProductService;
import com.burningtower.vo.CartProductVo;
import com.burningtower.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private CartRepository repository;
    @Autowired
    private ProductService productService;

    @Override
    public List<Cart> getListByUserId(@NotNull Integer userId) {
        Cart cart=new Cart();
        cart.setUserId(userId);
        return repository.findAll(Example.of(cart));
    }

    /**
     * 将当前用户的购物车列表转化为相应的VO
     * @param cartList
     * @return
     */
    @Override
    public CartVo toVo(List<Cart> cartList) {
        List<CartProductVo> cartProductVoList=new ArrayList<>();
        Boolean allChecked=true;
        BigDecimal totalPrice=new BigDecimal(0);
        for(Cart cart:cartList){
            Integer productId = cart.getProductId();
            Product product = productService.get(productId);
            CartProductVo cartProductVo=new CartProductVo();

            BeanUtils.copyProperties(cart,cartProductVo);
            cartProductVo.setProductName(product.getName());
            cartProductVo.setProductSubtitle(product.getSubtitle());
            cartProductVo.setProductMainImage("http://img.happymmall.com/"+product.getMainImage());
            cartProductVo.setProductPrice(product.getPrice());
            cartProductVo.setProductStatus(product.getStatus());
            cartProductVo.setProductTotalPrice(product.getPrice().multiply(BigDecimal.valueOf(cart.getQuantity())).setScale(2));
            cartProductVo.setProductStock(product.getStock());
            cartProductVo.setProductChecked(cart.getChecked());
            cartProductVo.setLimitQuantity(cart.getQuantity()<product.getStock()? LimitQuantity.LIMIT_NUM_SUCCESS:LimitQuantity.LIMIT_NUM_FAIL);
            cartProductVoList.add(cartProductVo);

            if (cart.getChecked()==0){//任意一个未选中则allChecked为false
                allChecked=false;
            }else{//选中则添加至总价
                totalPrice=totalPrice.add(cartProductVo.getProductTotalPrice());
            }
        }
        CartVo vo=new CartVo();
        vo.setAllChecked(allChecked);
        vo.setCartProductVoList(cartProductVoList);
        vo.setCartTotalPrice(totalPrice.setScale(2));
        return vo;
    }

    @Override
    public Cart add(Integer userId,Integer productId, Integer count) {
        productService.get(productId);//检查productId是否有效
        Cart cart=new Cart();
        cart.setProductId(productId);
        cart.setUserId(userId);
        if(repository.exists(Example.of(cart))){//如果购物车已经存在就直接增加数量。
            Cart one = repository.findOne(Example.of(cart));
            one.setQuantity(one.getQuantity()+count);
            return repository.save(one);
        }else{
            cart.setChecked(1);
            cart.setQuantity(count);
            cart.setCreateTime(new Date());
            cart.setUpdateTime(new Date());
            cart.setUserId(userId);
            return repository.save(cart);
        }
    }

    @Override
    public Cart update(Integer userId, Integer productId, Integer count) {
        Cart cart=new Cart();
        cart.setProductId(productId);
        cart.setUserId(userId);
        if(repository.exists(Example.of(cart))){
            Cart one = repository.findOne(Example.of(cart));
            one.setQuantity(count);
            return repository.save(one);
        }else{
            throw new RuntimeException("该商品不在购物车内");
        }
    }

    @Override
    public void delete(Integer id) {
        repository.delete(id);
    }

    @Override
    public void delete(Integer userId, Integer[] productIds) {
        for (Integer i:productIds){
            Cart cart=new Cart();
            cart.setProductId(i);
            cart.setUserId(userId);
            try {
                repository.delete(repository.findOne(Example.of(cart)));
            }catch (InvalidDataAccessApiUsageException e){
                throw new RuntimeException("该商品不在购物车内");
            }
        }
    }

    @Override
    public void select(Integer userId, Integer productId) {
        Cart cart=new Cart();
        cart.setProductId(productId);
        cart.setUserId(userId);
        if(repository.exists(Example.of(cart))){
            Cart one = repository.findOne(Example.of(cart));
            one.setChecked(1);
            repository.save(one);
        }else{
            throw new RuntimeException("该商品不在购物车内");
        }
    }

    @Override
    public void unSelect(Integer userId, Integer productId) {
        Cart cart=new Cart();
        cart.setProductId(productId);
        cart.setUserId(userId);
        if(repository.exists(Example.of(cart))){
            Cart one = repository.findOne(Example.of(cart));
            one.setChecked(0);
            repository.save(one);
        }else{
            throw new RuntimeException("该商品不在购物车内");
        }
    }

    @Override
    public Integer getCount(Integer userId) {
        Cart cart=new Cart();
        cart.setUserId(userId);
        return Math.toIntExact(repository.count(Example.of(cart)));
    }

    @Override
    public void selectAll(Integer userId) {
        Cart cart=new Cart();
        cart.setUserId(userId);
        List<Cart> cartList = repository.findAll(Example.of(cart));
        for(Cart c:cartList){
            if(c.getChecked()==0){
                c.setChecked(1);
                repository.save(c);
            }
        }
    }
    @Override
    public void unSelectAll(Integer userId) {
        Cart cart=new Cart();
        cart.setUserId(userId);
        List<Cart> cartList = repository.findAll(Example.of(cart));
        for(Cart c:cartList){
            if(c.getChecked()==1){
                c.setChecked(0);
                repository.save(c);
            }
        }
    }
}
